#include <string.h>
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
using std::ostream;

class String {
public:
    String()
        :m_pstr(new char[1]())
    {
        cout << "String()" << endl;
    }
    String(const char* pstr)
        :m_pstr(new char[strlen(pstr) + 1]())
    {
        strcpy(m_pstr, pstr);
        cout << "String(const char* pstr)" << endl;
    }
    String(const String& rhs)
        :m_pstr(new char[strlen(rhs.m_pstr) + 1]())
    {
        strcpy(m_pstr, rhs.m_pstr);
        cout << "String(const String& rhs)" << endl;
    }
    String& operator=(const String& rhs) {
        if (this != &rhs) {
            delete[] m_pstr;
            m_pstr = new char[strlen(rhs.m_pstr) + 1] {};
            strcpy(m_pstr, rhs.m_pstr);
        }
        cout << "String operator=(const String& rhs)" << endl;
        return *this;
    }
    //移动构造
    String(String&& rhs)
        :m_pstr(rhs.m_pstr)
    {
        rhs.m_pstr = nullptr;
        cout << "String(String&& rhs) 移动构造" << endl;
    }
    //移动赋值
    String& operator=(String&& rhs) {
        if (this != &rhs) {
            delete[] m_pstr;
            m_pstr = rhs.m_pstr;
            rhs.m_pstr = nullptr;
        }
        cout << "String operator=(String&& rhs) 移动赋值" << endl;
        return *this;
    }
    ~String() {
        if (m_pstr) {
            delete[] m_pstr;
            m_pstr = nullptr;
        }
        cout << "~String()" << endl;
    }
    friend ostream& operator<<(ostream& os, const String& rhs);
private:
    char* m_pstr;
};
ostream& operator<<(ostream& os, const String& rhs) {
    os << rhs.m_pstr;
    return os;
}

void test() {
    String s1;
    cout << s1 << endl;
    String s2 = s1;
    String s3 = "hello";
    cout << s3 << endl;
    s1 = s3;
    cout << s1 << endl;
    s2 = "nihao";
    cout << s2 << endl;
}
int main() {
    test();
    return 0;
}